import { BasePlugin } from '../plugin-system/base-plugin.js'
import { AutoCloseHandler, TextOperations, CursorOperations, ActionHandlers } from './utils/index.js'

/**
 * 键盘绑定插件
 * 处理各种键盘快捷键和自动闭合功能
 * 重构后采用模块化设计，将复杂功能拆分为专用工具类
 */
export class KeybindingPlugin extends BasePlugin {
    constructor(editor, options = {}) {
        super(editor, {
            // 默认配置
            autoCloseBrackets: true,
            autoCloseQuotes: true,
            tabSize: 4,
            fontSizeStep: 2,
            minFontSize: 10,
            maxFontSize: 30,
            keyBindings: {
                // 文件操作
                'Ctrl+S': 'save',
                'Ctrl+N': 'newFile',
                'Ctrl+O': 'openFile',
                
                // 撤销重做
                'Ctrl+Z': 'undo',
                'Ctrl+Shift+Z': 'redo',
                'Ctrl+Y': 'redo',
                
                // 搜索替换
                'Ctrl+F': 'find',
                'Ctrl+H': 'replace',
                'F3': 'findNext',
                'Shift+F3': 'findPrevious',
                'Ctrl+G': 'goToLine',
                
                // 文本选择
                'Ctrl+A': 'selectAll',
                'Ctrl+L': 'selectLine',
                'Ctrl+D': 'selectWordAtCursor',
                'Ctrl+Shift+L': 'selectAllOccurrences',
                
                // 剪切复制粘贴
                'Ctrl+X': 'cut',
                'Ctrl+C': 'copy',
                'Ctrl+V': 'paste',
                
                // 行操作
                'Ctrl+Shift+K': 'deleteLine',
                'Ctrl+Shift+D': 'duplicateLine',
                'Alt+UpArrow': 'moveLineUp',
                'Alt+DownArrow': 'moveLineDown',
                'Ctrl+Shift+Enter': 'insertLineAbove',
                'Ctrl+Enter': 'insertLineBelow',
                
                // 注释
                'Ctrl+/': 'toggleLineComment',
                'Ctrl+Shift+/': 'toggleBlockComment',
                
                // 缩进
                'Ctrl+]': 'indent',
                'Ctrl+[': 'outdent',
                'Ctrl+Shift+\\': 'jumpToBracket',
                
                // 光标移动
                'Ctrl+LeftArrow': 'cursorWordLeft',
                'Ctrl+RightArrow': 'cursorWordRight',
                'Home': 'cursorHome',
                'End': 'cursorEnd',
                'Ctrl+Home': 'cursorTop',
                'Ctrl+End': 'cursorBottom',
                
                // 文本变换
                'Ctrl+Shift+U': 'transformToUppercase',
                'Ctrl+U': 'transformToLowercase',
                
                // 字体大小
                'Ctrl+=': 'increaseFontSize',
                'Ctrl+-': 'decreaseFontSize',
                'Ctrl+0': 'resetFontSize',
                
                // 其他
                'Ctrl+Enter': 'runCode',
                'F11': 'toggleFullscreen',
                'Escape': 'escape'
            },
            ...options
        })
        
        // 初始化工具处理器
        this.initializeHandlers()
    }
    
    /**
     * 初始化各种处理器
     */
    initializeHandlers() {
        this.autoCloseHandler = new AutoCloseHandler(this.editor, this.options)
        this.textOperations = new TextOperations(this.editor, this.options)
        this.cursorOperations = new CursorOperations(this.editor)
        this.actionHandlers = new ActionHandlers(this.editor, this.options)
    }
    
    initialize() {
        // 插件初始化逻辑
        this.initializeHandlers()
    }
    
    onEnable() {
        // 监听键盘事件
        this.editor.on('editor:keydown', this.handleKeyDown.bind(this))
        
        this.emit('keybinding:enabled')
    }
    
    onDisable() {
        // 移除事件监听
        this.editor.off('editor:keydown', this.handleKeyDown.bind(this))
        
        this.emit('keybinding:disabled')
    }
    
    /**
     * 处理键盘按下事件
     */
    handleKeyDown(data) {
        const e = data.event
        
        // 构建快捷键字符串
        const keyString = this.buildKeyString(e)
        const action = this.options.keyBindings[keyString]
        
        if (action) {
            // 对于粘贴操作，先检查是否支持现代剪贴板 API
            if (action === 'paste') {
                // 如果不支持现代剪贴板 API，则不阻止默认行为
                if (!navigator.clipboard || !navigator.clipboard.readText) {
                    // 不阻止默认行为，让浏览器处理粘贴
                    setTimeout(() => {
                        this.editor._updateEditor()
                        this.emit('keybinding:paste')
                    }, 0)
                    return false
                } else {
                    // 支持现代 API，尝试执行操作
                    const handled = this.executeAction(action, e)
                    if (handled) {
                        e.preventDefault()
                        e.stopPropagation()
                        e.stopImmediatePropagation()
                        return true
                    } else {
                        // 如果处理失败，不阻止默认行为
                        return false
                    }
                }
            } else {
                // 其他操作立即阻止默认行为
                e.preventDefault()
                e.stopPropagation()
                e.stopImmediatePropagation()
                this.executeAction(action, e)
                return true // 返回true表示事件已被处理
            }
        }
        
        // 处理Tab键（需要检查自动补全状态）
        if (e.key === 'Tab') {
            return this.handleTabKey(e)
        }
        
        // 处理自动闭合
        if (this.autoCloseHandler.handleKeyDown(e)) {
            return true
        }
        
        // 如果没有处理任何事件，返回false
        return false
    }
    
    /**
     * 处理Tab键（检查自动补全状态）
     */
    handleTabKey(e) {
        // 检查是否有自动补全弹窗显示
        const autocompletePlugin = this.editor.getPlugin('AutoCompletePlugin')
        const isAutocompleteVisible = autocompletePlugin && 
            this.editor.autocompletePopupDom && 
            this.editor.autocompletePopupDom.style.display === 'block'
        
        if (!isAutocompleteVisible) {
            e.preventDefault()
            if (e.shiftKey) {
                this.textOperations.handleOutdent()
            } else {
                this.textOperations.handleIndent()
            }
            return true
        }
        return false
    }
    
    /**
     * 构建快捷键字符串
     */
    buildKeyString(e) {
        const parts = []
        
        if (e.ctrlKey || e.metaKey) parts.push('Ctrl')
        if (e.altKey) parts.push('Alt')
        if (e.shiftKey) parts.push('Shift')
        
        // 处理特殊键
        let key = e.key
        if (key === 'ArrowUp') key = 'UpArrow'
        else if (key === 'ArrowDown') key = 'DownArrow'
        else if (key === 'ArrowLeft') key = 'LeftArrow'
        else if (key === 'ArrowRight') key = 'RightArrow'
        else if (key === ' ') key = 'Space'
        else if (key === '\\') key = '\\\\' // 转义反斜杠
        else if (key.length === 1 && /[a-z]/.test(key)) {
            // 将单个字母转换为大写
            key = key.toUpperCase()
        }
        
        parts.push(key)
        
        return parts.join('+')
    }
    
    /**
     * 执行快捷键动作
     * @param {string} action - 动作名称
     * @param {Event} event - 键盘事件
     * @returns {boolean} 操作是否成功执行
     */
    executeAction(action, event) {
        switch (action) {
            // 文件操作
            case 'save':
                return this.actionHandlers.handleSave()
            case 'newFile':
                return this.actionHandlers.handleNewFile()
            case 'openFile':
                this.actionHandlers.handleOpenFile()
                return true
                
            // 撤销重做
            case 'undo':
                return this.actionHandlers.handleUndo()
            case 'redo':
                return this.actionHandlers.handleRedo()
                
            // 搜索替换
            case 'find':
                this.actionHandlers.handleFind()
                return true
            case 'replace':
                this.actionHandlers.handleReplace()
                return true
            case 'findNext':
                this.actionHandlers.handleFindNext()
                return true
            case 'findPrevious':
                this.actionHandlers.handleFindPrevious()
                return true
            case 'goToLine':
                return this.actionHandlers.handleGoToLine()
                
            // 文本选择
            case 'selectAll':
                this.cursorOperations.selectAll()
                this.emit('keybinding:selectAll')
                return true
            case 'selectLine':
                this.textOperations.selectLine()
                this.emit('keybinding:selectLine')
                return true
            case 'selectWordAtCursor':
                if (this.textOperations.selectWordAtCursor()) {
                    this.emit('keybinding:selectWordAtCursor')
                    return true
                }
                return false
            case 'selectAllOccurrences':
                this.actionHandlers.handleSelectAllOccurrences()
                return true
                
            // 剪切复制粘贴
            case 'cut':
                return this.actionHandlers.handleCut()
            case 'copy':
                return this.actionHandlers.handleCopy()
            case 'paste':
                return this.actionHandlers.handlePaste()
                
            // 行操作
            case 'deleteLine':
                this.textOperations.deleteLine()
                this.emit('keybinding:deleteLine')
                return true
            case 'duplicateLine':
                this.textOperations.duplicateLine()
                this.emit('keybinding:duplicateLine')
                return true
            case 'moveLineUp':
                if (this.textOperations.moveLineUp()) {
                    this.emit('keybinding:moveLineUp')
                    return true
                }
                return false
            case 'moveLineDown':
                if (this.textOperations.moveLineDown()) {
                    this.emit('keybinding:moveLineDown')
                    return true
                }
                return false
            case 'insertLineAbove':
                this.textOperations.insertLineAbove()
                this.emit('keybinding:insertLineAbove')
                return true
            case 'insertLineBelow':
                this.textOperations.insertLineBelow()
                this.emit('keybinding:insertLineBelow')
                return true
                
            // 注释
            case 'toggleLineComment':
                this.textOperations.toggleLineComment()
                this.emit('keybinding:toggleLineComment')
                return true
            case 'toggleBlockComment':
                this.textOperations.toggleBlockComment()
                this.emit('keybinding:toggleBlockComment')
                return true
                
            // 缩进
            case 'indent':
                this.textOperations.handleIndent()
                return true
            case 'outdent':
                this.textOperations.handleOutdent()
                return true
            case 'jumpToBracket':
                this.actionHandlers.handleJumpToBracket()
                return true
                
            // 光标移动
            case 'cursorWordLeft':
                this.cursorOperations.cursorWordLeft()
                return true
            case 'cursorWordRight':
                this.cursorOperations.cursorWordRight()
                return true
            case 'cursorHome':
                this.cursorOperations.cursorHome()
                return true
            case 'cursorEnd':
                this.cursorOperations.cursorEnd()
                return true
            case 'cursorTop':
                this.cursorOperations.cursorTop()
                return true
            case 'cursorBottom':
                this.cursorOperations.cursorBottom()
                return true
                
            // 文本变换
            case 'transformToUppercase':
                if (this.textOperations.transformToUppercase()) {
                    this.emit('keybinding:transformToUppercase')
                    return true
                }
                return false
            case 'transformToLowercase':
                if (this.textOperations.transformToLowercase()) {
                    this.emit('keybinding:transformToLowercase')
                    return true
                }
                return false
                
            // 字体大小
            case 'increaseFontSize':
                this.actionHandlers.changeFontSize('+')
                return true
            case 'decreaseFontSize':
                this.actionHandlers.changeFontSize('-')
                return true
            case 'resetFontSize':
                this.actionHandlers.resetFontSize()
                return true
                
            // 其他
            case 'runCode':
                this.actionHandlers.handleRunCode()
                return true
            case 'toggleFullscreen':
                this.actionHandlers.handleToggleFullscreen()
                return true
            case 'escape':
                this.actionHandlers.handleEscape()
                return true
                
            default:
                // 发射自定义动作事件
                this.emit('keybinding:action', { action, event })
                return true
        }
    }
    
    /**
     * 自定义快捷键绑定
     */
    addKeyBinding(key, action) {
        this.options.keyBindings[key] = action
    }
    
    /**
     * 移除快捷键绑定
     */
    removeKeyBinding(key) {
        delete this.options.keyBindings[key]
    }
    
    /**
     * 获取所有快捷键绑定
     */
    getKeyBindings() {
        return { ...this.options.keyBindings }
    }
    
    /**
     * 更新配置
     */
    updateOptions(newOptions) {
        this.options = { ...this.options, ...newOptions }
        
        // 更新各个处理器的配置
        this.autoCloseHandler.updateOptions(this.options)
        this.textOperations.updateOptions(this.options)
        this.actionHandlers.updateOptions(this.options)
    }
    
    /**
     * 获取光标操作工具
     */
    getCursorOperations() {
        return this.cursorOperations
    }
    
    /**
     * 获取文本操作工具
     */
    getTextOperations() {
        return this.textOperations
    }
    
    /**
     * 发射事件的便捷方法
     */
    emit(event, data) {
        this.editor.emit(event, data)
    }
}
